fix: route datamate tools through local stdio mcp-engine instead of cloud#893
fix: route datamate tools through local stdio mcp-engine instead of cloud#893altimate-harness-bot[bot] wants to merge 3 commits into
Conversation
|
This PR doesn't fully meet our contributing guidelines and PR template. What needs to be fixed:
Please edit this PR description to address the above within 2 hours, or it will be automatically closed. If you believe this was flagged incorrectly, please let a maintainer know. |
|
Thanks for your contribution! This PR doesn't have a linked issue. All PRs must reference an existing issue. Please:
See CONTRIBUTING.md for details. |
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
E2E Verification — PASSED ✓Full pipeline tested end-to-end in the sandbox: Test setup:
Results: What was verified:
|
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
15 similar comments
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
- Add stdio transport support for datamate MCP (vs HTTP-only before) - Single-gateway mode: when .vscode/mcp.json has "datamate" key, always use it as server name — prevents duplicate tool sets from extension - syncDatamateUrlFromVscodeMcp: use updatedAt field as change signal for the "datamate" entry (works for both stdio and HTTP), URL comparison for all other remote entries - Strip ALTIMATE_EXTENSION_RPC from persisted mcp-discover configs to avoid stale socket paths across VS Code sessions - persistMcpEnabled: write enabled/disabled flag to disk on MCP connect/disconnect so it survives session restarts - Add /altimate/mcp/reload-datamate endpoint to re-sync and reconnect without full server restart - MCP.ToolsChanged subscription in prompt loop for traceability - Merge main: preserve trace consumer in serve.ts, restore exports on isAnthropicLikeModel and insertReminders
a71092d to
0b6cc26
Compare
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
1 similar comment
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
) Co-authored-by: saravmajestic <[email protected]>
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
1 similar comment
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
| projectRootDir: string, | ||
| ): Promise<{ type: "remote"; url: string } | { type: "local" } | null> { | ||
| try { | ||
| const mcpJsonPath = path.join(projectRootDir, ".vscode", "mcp.json") |
There was a problem hiding this comment.
this will not be in .vscode always, it will differ according to the IDE used. We should scan across projectRootDir
| "global config is at ~/.config/altimate-code/altimate-code.json. " + | ||
| "Datamate server names are prefixed with 'datamate-'. " + | ||
| "When a VS Code extension datamate entry exists (.vscode/mcp.json has 'datamate' key), " + | ||
| "'add' always uses the server name 'datamate' — tools are then prefixed 'datamate_'. " + |
| for (const [key, entry] of Object.entries(serversMap)) { | ||
| const args = Array.isArray(entry["args"]) ? (entry["args"] as string[]) : [] | ||
| const isDatamate = | ||
| key === "datamate" || |
There was a problem hiding this comment.
can use EXTENSION_DATAMATE_SERVER instead of string?
| : transport?.type === "local" | ||
| // Extension stdio: no --datamate id needed — active teammate is resolved | ||
| // by the extension over the ALTIMATE_EXTENSION_RPC socket at runtime. | ||
| ? { type: "local" as const, command: ["datamate", "start-stdio"] } |
There was a problem hiding this comment.
isnt this supposed to be same as in .vscode/mcp.json, so that it can re use the same process? Otherwise we will be maintaining 2 processes?
| // Stripping it forces runtime discovery via ~/.altimate/extension-rpc/ sidecars, | ||
| // which always resolves the correct live bridge by matching process.cwd() against | ||
| // each bridge's recorded workspaceFolders. | ||
| function stripSessionEnv(cfg: import("../../config/config").Config.Mcp): import("../../config/config").Config.Mcp { |
There was a problem hiding this comment.
Ideal case is to use same process. May be we can expose a cleanup function, which can be called by extension on deactivate or window close? Or actually, when window is closed, this altimate code process will also be killed right?
| import { subscribeTraceConsumer } from "../../altimate/observability/trace-consumer" | ||
| // altimate_change end | ||
|
|
||
| // altimate_change start |
There was a problem hiding this comment.
this logic could better be in separate file
| // All other remote MCP entries fall back to URL comparison (original behaviour). | ||
| // Fire-and-forget: errors are logged but never thrown. | ||
| // Returns the list of MCP server names whose config was updated. | ||
| const DATAMATE_KEY = "datamate" |
There was a problem hiding this comment.
repeated constant. lets extract to common constant
| export async function syncDatamateUrlFromVscodeMcp(cwd: string): Promise<string[]> { | ||
| const updated: string[] = [] | ||
| try { | ||
| const mcpJsonPath = path.join(cwd, ".vscode", "mcp.json") |
| // check would miss the gateway-emitted specific names (#888 J1). The api.id | ||
| // checks are lowercased and tightened to a `claude-` / `anthropic-` / | ||
| // `anthropic/...` shape so a model named `foo-claude-bench` doesn't false-match. | ||
| // |
There was a problem hiding this comment.
why is this removed? same for below comment block
…+ improve logging
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
1 similar comment
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
Problem
DatamateManagerTool.handleAdd()was creating MCP server entries pointing to the cloud MCP server (https://mcpserver.getaltimate.com) becausebuildMcpConfig()always fell back toDEFAULT_MCP_URLwhenmcpServerUrlwas absent fromaltimate.json.The cloud MCP runs in multi-user mode and reads connections from API headers — it has no access to
~/.altimate/connections.json. So any tool call likedatamate-remote_jira_get_issuefailed with "No connection configured for integration: jira" even when connections were configured locally.Fix
datamate.ts—handleAdd()Replace
buildMcpConfig()(HTTP remote) with a local stdio config:Each spawned
datamate start-stdioprocess:connections.jsonfrom~/.altimate/directly (local engine, same as VS Code extension)~/.altimate/extension-rpc/workspaceFolders; the spawned process matches onprocess.cwd()(set to project root byStdioClientTransport) and routes to the right bridge automaticallymcp-discover.ts—stripSessionEnv()When persisting a discovered server via
mcp_discover, stripALTIMATE_EXTENSION_RPCfrom the environment block before writing to disk. The socket path is session-specific (unique to the current extension host process) — hardcoding it would cause future sessions to connect to a dead or wrong bridge. Stripping it forces runtime discovery.Prerequisites
Requires the global
datamateCLI to be on PATH:npm install -g @altimateai/datamate. The VS Code extension already warns users when stdio mode is configured but no globaldatamateis found.Related PRs
mcpServerUrltoaltimate.json(interim fix, superseded by this approach)Requested by @saravmajestic via harness
Summary by cubic
Route
datamatetools through the local MCP engine when an IDE MCP entry exists, auto-detecting stdio vs HTTP from IDE configs and reusing the IDE’s process. Consolidates tools behind a singledatamategateway, adds live reload, and keeps config and enabled state in sync across restarts.Bug Fixes
datamate.ts: detect transport from.vscode/mcp.json,.cursor/mcp.json,.github/copilot/mcp.json; reuse IDE command; use server namedatamatewhen an IDE entry exists, otherwise fall back to per-datamate cloud config; persistenabled: true; reconnect existing entries withMCP.connectto preserve enabled state; avoids duplicate stdio processes.altimate/datamate-transport.ts: new helpers (DATAMATE_KEY,readDatamateTransportFromIde,syncDatamateUrlFromVscodeMcp,readMcpEntryFromDisk); sync thedatamateentry byupdatedAt(covers stdio + HTTP); URL-compare for other remote entries.~/.altimate/connections.jsonand cwd-matched sidecars to route to the right VS Code bridge; supports multiple windows.mcp-discover.ts: stripALTIMATE_EXTENSION_RPCbefore persisting to avoid stale/dead sockets.serve.ts+config.ts: syncdatamatefrom IDE MCP config on startup; persistupdatedAtin config.server.ts: addPOST /altimate/mcp/reload-datamate; bypass stale in-memory config by reading fresh entries from disk and reconnect withMCP.add(no restart, no enabled flag clobber).session/prompt.ts: subscribe toMCP.ToolsChangedand refresh tools on the next turn with trace logs.mcp/index.ts: persistenabled/disabledto config on connect/disconnect so it survives restarts.command/index.ts: add/mcpscommand to list MCP servers and status (AI-6948).Migration
datamateCLI is on PATH:npm install -g @altimateai/datamate.Written for commit 520143f. Summary will update on new commits.